namespace CodingWheels.DataTypes.Core
{
	public class Conversion
	{
		private readonly double _factor;

		internal UnitSet UnitSet
		{
			get;
			private set;
		}

		internal Conversion(Unit fromUnit, Unit toUnit, double factor)
		{
			_factor = factor;
			UnitSet = new UnitSet(fromUnit, toUnit);
		}

		public double Convert(double value, Unit fromUnit, Unit toUnit)
		{
			if(fromUnit.Equals(toUnit))
			{
				return value;
			}

			if(UseInverseConversion(fromUnit))
			{
				return value / _factor;
			}

			return value * _factor;
		}

		private bool UseInverseConversion(Unit fromUnit)
		{
			return !UnitSet.FromUnit.Equals(fromUnit);
		}
		
	}

	public class Conversion<T> : Conversion where T : Unit
	{
		private Conversion(T fromUnit, T toUnit, double factor) : base(fromUnit, toUnit, factor)
		{
		}

		public static Conversion<T> ConvertUsingMultiplication(T fromUnit, T toUnit, double factor)
		{
			return new Conversion<T>(fromUnit, toUnit, factor);
		}

		public static Conversion<T> ConvertUsingDivision(T fromUnit, T toUnit, double divisor)
		{
			return new Conversion<T>(toUnit, fromUnit, divisor);
		}
	}
}